package com.leo.foodmaster.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leo.foodmaster.admin.system.entity.Organ;
import com.leo.foodmaster.admin.system.entity.Role;
import com.leo.foodmaster.admin.system.entity.RolePermission;
import com.leo.foodmaster.admin.system.entity.UserRole;
import com.leo.foodmaster.admin.system.mapper.RoleMapper;
import com.leo.foodmaster.admin.system.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leo.foodmaster.commons.entity.Result;
import com.leo.foodmaster.commons.enums.OrganTypeEnum;
import com.leo.foodmaster.commons.enums.StatusEnum;
import com.leo.foodmaster.commons.util.WebUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author Leo
 * @since 2021-06-18
 */
@Service
@AllArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    private final IOrganService organService;
    private final IRolePermissionService rolePermissionService;
    private final IUserRoleService userRoleService;
    private final IPermissionService permissionService;


    /**
     * 分页条件查询角色列表
     * @param page 分页参数
     * @param name 角色名称
     * @param status 状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<Role>
     */
    @Override
    public IPage<Role> getRolePageList(Page<Role> page, String name, Long organId,
                                       String status, String beginTime, String endTime) {
        String organType = WebUtils.getUser().getOrganType();
        LambdaQueryWrapper<Role> qw = Wrappers.lambdaQuery(Role.class)
                .like(StrUtil.isNotBlank(name), Role::getName, name)
                .eq(StrUtil.isNotEmpty(status), Role::getStatus, status)
                .ge(StrUtil.isNotBlank(beginTime), Role::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), Role::getCreateTime, endTime);
        if (organType.equals(OrganTypeEnum.PLATFORM.getCode())) {
            qw.eq(BeanUtil.isNotEmpty(organId), Role::getOrganId, organId);
        }else {
            qw.eq(Role::getOrganId, WebUtils.getUser().getOrganId());
        }
        return page(page, qw);
    }

    /**
     * 新增角色
     * @param role 角色信息
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> addRole(Role role) {
        // 新增角色信息
        Organ organ = organService.getById(role.getOrganId());
        role.setOrganName(organ.getName());
        save(role);
        // 新增角色权限关系信息
        addRolePermission(role);

        return Result.success();
    }

    /**
     * 新增角色权限关系
     * @param role 角色信息
     */
    private void addRolePermission(Role role) {
        List<Long> permissionIds = role.getPermissionIds();
        if (!permissionIds.isEmpty()) {
            List<RolePermission> list = new ArrayList<>();
            permissionIds.forEach(permissionId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setRoleId(role.getId());
                rolePermission.setPermissionId(permissionId);
                list.add(rolePermission);
            });
            rolePermissionService.saveBatch(list);
            // 刷新Redis中的权限角色关系
            permissionService.refreshPermissionRolesToCache();
        }
    }

    /**
     * 修改角色
     * @param role 角色信息
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updateRole(Role role) {
        // 修改角色信息
        Organ organ = organService.getById(role.getOrganId());
        role.setOrganName(organ.getName());
        updateById(role);

        // 修改角色权限关系信息，首先删除原来的角色权限关系信息
        rolePermissionService.remove(Wrappers.lambdaUpdate(RolePermission.class)
        .eq(RolePermission::getRoleId, role.getId()));
        // 新增角色权限关系信息
        addRolePermission(role);

        return Result.success();
    }

    /**
     * 删除角色
     * @param roleIds 角色Ids
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> deleteRole(String roleIds) {
        String[] roleIdArray = roleIds.split(StrUtil.COMMA);
        for (String roleId : roleIdArray) {
            // 如果该角色正在被用户使用，则不能删除该角色
            int count = userRoleService.count(Wrappers.lambdaQuery(UserRole.class)
                    .eq(UserRole::getRoleId, roleId));
            if (count != 0) {
                return Result.fail("该角色正在被用户使用，不能删除！");
            }
            // 删除用户角色关系表
            userRoleService.remove(Wrappers.lambdaUpdate(UserRole.class)
            .eq(UserRole::getRoleId, roleId));
            // 删除角色权限关系表
            rolePermissionService.remove(Wrappers.lambdaUpdate(RolePermission.class)
                    .eq(RolePermission::getRoleId, roleId));
            // 删除角色表
            removeById(roleId);
        }
        // 刷新Redis中的权限角色关系
        permissionService.refreshPermissionRolesToCache();
        return Result.success();
    }

    /**
     * 修改角色状态
     * @param role 角色状态信息
     * @return Result<Object>
     */
    @Override
    public Result<Object> updateStatus(Role role) {
        // 如果角色对应的公司状态为禁用，则不能修改角色状态
        String organStatus = baseMapper.getOrganStatus(role.getId());
        if (StrUtil.isNotBlank(organStatus) && StatusEnum.DISABLED.getCode().equals(organStatus)) {
            return Result.fail("该角色对应的公司被禁用，该角色不能被启用！");
        }
        updateById(role);
        return Result.success();
    }
}
